前一篇與大家介紹了 Selenium 的基本運用,並在補充資料中給予了語法的資源。
今天要帶各位寫一隻能夠爬取 Dcard 上文章的爬蟲,是透過 Selenium 去撰寫。
透過 Selenium 成功開啟 Dcard 分頁(瀏覽器分頁)
用 Selenium 內建的鎖定工具爬取目前的所有文章
將文章存於 JSON 檔案中
首先,先簡單撰寫一個 Selenium ,讓 Selenium 去開 Dcard 網站 https://www.dcard.tw/f。
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')
接下來用開發工具觀察一下文章元素是否有 class 讓我們爬取。發現有 tgn9uw-0 bReysV 這個 class。
我們可以用 driver.find_elements_by_class_name
來定位該元素們,並用個 for-loop 將回傳的 list 遍歷過一遍後輸出。
如果沒有鎖定到,有可能是還沒有載入完成就爬取造成的,這時候我們能用 time 庫裡面的 sleep 來讓整個程式暫停 0.5 秒讓資源載入完成。
from selenium import webdriver
from time import sleep
if __name__ == '__main__':
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')
sleep(2)
eles = driver.find_elements_by_class_name('tgn9uw-0')
for ele in eles:
print(ele)
driver.quit()
'''
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="ee2da9f1-a5d0-41fc-80d7-63bf394e7267")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="02573927-21b1-405c-9310-8a050aa6ec8f")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="584200b4-5633-44f4-a048-e2bd3ebeb636")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="aa05e5c6-defb-4087-84b3-a9d6dbe4131d")>
<selenium.webdriver.remote.webelement.WebElement (session="753badfd9b587e097ab5e821cf9604eb", element="85badbb3-7238-4b6e-9892-b7e71e8ac2f9")>
'''
將標題、連結、副標鎖定後存到變數中。
from selenium import webdriver
from time import sleep
if __name__ == '__main__':
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')
sleep(2)
eles = driver.find_elements_by_class_name('tgn9uw-0')
for ele in eles:
title = ele.find_element_by_class_name('tgn9uw-3').text
href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
subtitle = ele.find_element_by_class_name('tgn9uw-4').text
print(title)
print(href)
print(subtitle)
driver.quit()
將結果存於一個 dist 中,並 append 到總結果當中。
from selenium import webdriver
from time import sleep
if __name__ == '__main__':
results = []
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')
sleep(2)
eles = driver.find_elements_by_class_name('tgn9uw-0')
for ele in eles:
result = {}
title = ele.find_element_by_class_name('tgn9uw-3').text
href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
subtitle = ele.find_element_by_class_name('tgn9uw-4').text
result = {
'title': title,
'href': href,
'subtitle': subtitle
}
results.append(result)
print(results)
driver.quit()
接下來將結果存於 JSON 檔案中。
from selenium import webdriver
from time import sleep
import json
if __name__ == '__main__':
results = []
driver = webdriver.Chrome()
driver.get('https://www.dcard.tw/f')
sleep(2)
eles = driver.find_elements_by_class_name('tgn9uw-0')
for ele in eles:
result = {}
title = ele.find_element_by_class_name('tgn9uw-3').text
href = ele.find_element_by_class_name('tgn9uw-3').get_attribute('href')
subtitle = ele.find_element_by_class_name('tgn9uw-4').text
result = {
'title': title,
'href': href,
'subtitle': subtitle
}
results.append(result)
print(results)
with open('Dcard-articles.json', 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2,
sort_keys=True, ensure_ascii=False)
driver.quit()
今天分析了文章的元素特徵,用了 Selenium 模擬使用者鎖定所有文章的元素,之後操作鎖定到的元素將其存在變數中,整理到一個字典,並塞入一個串列中,最後將串列存到 JSON 檔案中。
明天將用 Selenium 模擬使用者滾動頁面(划手機 or 滾輪),並將文章爬取下來。
Dcard : https://www.dcard.tw/f
Selenium with Python docs : https://selenium-python.readthedocs.io/
Selenium docs : https://readthedocs.org/projects/selenium-python/downloads/pdf/latest/
學習中…但目前的網頁的 article class的元素似乎找不太到…一整串很長!可以解答一下嗎,謝謝。:)
我剛稍微看了一下還有,看要不要使用隨機等待[1]的方式讓資料渲染完,或者直接使用比較推薦的 Dcard API [2]抓資料。
[1] __import__("time").sleep(__import__("random").randint(2, 5))
[2]https://www.dcard.tw/service/api/v2/posts